/* Copyright (c) Soon.Liao 2024. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * Create Date : 2024
 * @Date: 2024-10-14 07:57:06
 * @LastEditors: soon.liao
 * @LastEditTime: 2024-10-26 14:02:04
 * @FilePath: /src/application/ws63/rgb_master/common/cmd_json.c
 * @Description: NA
 * NA
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "securec.h"
#include "cJSON.h"

#include "soc_osal.h"

#include "ssd1306.h"
#include "key_value.h"

#include "cmd_json.h"

#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
#include "sle_server.h"
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT)
#include "sence.h"
#endif /* CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT */

#include "hal_reboot.h"

void oled_show_data(char *data, uint32_t len)
{
    int x = 0;
    int y = 40;
    char tmp_data[MAX_FONT_7_10_IN_ONE_LINE];
    // Use space character to clear Oled display
    memset(tmp_data, CHAR_SPACE, MAX_FONT_7_10_IN_ONE_LINE);
    memcpy(tmp_data, data, len);
    tmp_data[MAX_FONT_7_10_IN_ONE_LINE] = CHAR_END;
    ssd1306_set_cursor(x, y);
    ssd1306_draw_string(tmp_data, g_font_7x10, WHITE);
    ssd1306_update_screen();
    osal_printk("oled_show_data data:%s len:%d\n", data, len);
    free(tmp_data);
}

#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
int create_json_paj7620u2_cammand(char *string)
{
    // 创建一个空的 JSON 对象
    if (string == NULL) {
        return 1;
    }
    oled_show_data(string, strlen(string));
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        osal_printk("Error before: [%s]\n", cJSON_GetErrorPtr());
        return 1;
    }
    // 向 JSON 对象中添加键值对
    cJSON_AddStringToObject(root, CMD_TYPE, CMD_TYPE_PAJ7620U2);
    cJSON_AddStringToObject(root, CMD_NAME_CMD, (const char *const)string);
    // 将 JSON 对象序列化为字符串
    char *json_string = cJSON_Print(root);
    if (json_string == NULL) {
        osal_printk("Failed to print JSON\n");
        cJSON_Delete(root);
        return 1;
    }

    // 输出 JSON 字符串
    osal_printk("Generated JSON:\n%s\n", json_string);
    sle_uart_server_send_report_by_handle((const uint8_t *)json_string, (uint16_t)strlen(json_string));
    // 清理内存
    cJSON_Delete(root);
    free(json_string);

    return 0;
}

int create_json_wifi_cammand(char *string)
{
    if (string == NULL) {
        return 1;
    }
    oled_show_data(string, strlen(string));
    // 创建一个空的 JSON 对象
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        osal_printk("Error before: [%s]\n", cJSON_GetErrorPtr());
        return 1;
    }

    // 向 JSON 对象中添加键值对
    cJSON_AddStringToObject(root, CMD_TYPE, CMD_TYPE_WIFI_CMD);
    cJSON_AddStringToObject(root, CMD_NAME_CMD, string);
    // 将 JSON 对象序列化为字符串
    char *json_string = cJSON_Print(root);
    if (json_string == NULL) {
        osal_printk("Failed to print JSON\n");
        cJSON_Delete(root);
        return 1;
    }
    // 输出 JSON 字符串
    osal_printk("Generated JSON:\n%s\n", json_string);
    sle_uart_server_send_report_by_handle((const uint8_t *)json_string, (uint16_t)strlen(json_string));
    // 清理内存
    cJSON_Delete(root);
    free(json_string);
    return 0;
}

int create_json_wifi_info(char *ssid, char *password)
{
    if (ssid == NULL || password == NULL) {
        return 1;
    }

    // 创建一个空的 JSON 对象
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        osal_printk("Error before: [%s]\n", cJSON_GetErrorPtr());
        return 1;
    }

    // 向 JSON 对象中添加键值对
    cJSON_AddStringToObject(root, CMD_TYPE, CMD_TYPE_WIFI_INFO);
    cJSON_AddStringToObject(root, CMD_NAME_SSID, ssid);
    cJSON_AddStringToObject(root, CMD_NAME_PASSWD, password);

    // 将 JSON 对象序列化为字符串
    char *json_string = cJSON_Print(root);
    if (json_string == NULL) {
        osal_printk("Failed to print JSON\n");
        cJSON_Delete(root);
        return 1;
    }

    // 输出 JSON 字符串
    osal_printk("Generated JSON:\n%s\n", json_string);
    sle_uart_server_send_report_by_handle((const uint8_t *)json_string, (uint16_t)strlen(json_string));
    // 清理内存
    cJSON_Delete(root);
    free(json_string);

    return 0;
}

int create_json_wifi_led_num(char *string)
{
    if (string == NULL) {
        return 1;
    }
    oled_show_data(string, strlen(string));
    // 创建一个空的 JSON 对象
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        osal_printk("Error before: [%s]\n", cJSON_GetErrorPtr());
        return 1;
    }

    // 向 JSON 对象中添加键值对
    cJSON_AddStringToObject(root, CMD_TYPE, CMD_TYPE_LED_NUM);
    cJSON_AddStringToObject(root, CMD_NAME_VALUE, string);

    // 将 JSON 对象序列化为字符串
    char *json_string = cJSON_Print(root);
    if (json_string == NULL) {
        osal_printk("Failed to print JSON\n");
        cJSON_Delete(root);
        return 1;
    }

    // 输出 JSON 字符串
    osal_printk("Generated JSON:\n%s\n", json_string);
    sle_uart_server_send_report_by_handle((const uint8_t *)json_string, (uint16_t)strlen(json_string));
    // 清理内存
    cJSON_Delete(root);
    free(json_string);

    return 0;
}

int create_json_wifi_brightness(char *string)
{
    if (string == NULL) {
        return 1;
    }
    oled_show_data((char *)string, strlen(string));
    // 创建一个空的 JSON 对象
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        osal_printk("Error before: [%s]\n", cJSON_GetErrorPtr());
        return 1;
    }

    // 向 JSON 对象中添加键值对
    cJSON_AddStringToObject(root, CMD_TYPE, CMD_TYPE_BRIGHTNESS);
    cJSON_AddStringToObject(root, CMD_NAME_VALUE, string);

    // 将 JSON 对象序列化为字符串
    char *json_string = cJSON_Print(root);
    if (json_string == NULL) {
        osal_printk("Failed to print JSON\n");
        cJSON_Delete(root);
        return 1;
    }

    // 输出 JSON 字符串
    osal_printk("Generated JSON:\n%s\n", json_string);
    sle_uart_server_send_report_by_handle((const uint8_t *)json_string, (uint16_t)strlen(json_string));
    // 清理内存
    cJSON_Delete(root);
    free(json_string);

    return 0;
}

#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT)

// Gesture detection string
#define STR_UP "Up"
#define STR_DOWN "Down"
#define STR_LEFT "Left"
#define STR_RIGHT "Right"
#define STR_FORWARD "Forward"
#define STR_BACKWARD "Backward"
#define STR_CLOCKWISE "Clockwise"
#define STR_COUNT_CLOCKWISE "AntiClockwise"
#define STR_WAVE "Wave"

#define STR_UP_LEN 2
#define STR_DOWN_LEN 4
#define STR_LEFT_LEN 4
#define STR_RIGHT_LEN 5
#define STR_FORWARD_LEN 7
#define STR_BACKWARD_LEN 8
#define STR_CLOCKWISE_LEN 9
#define STR_COUNT_CLOCKWISE_LEN 13
#define STR_WAVE_LEN 4

void handle_paj7620_cb_para(char *paj7220_data)
{
    osal_printk("\n %s(%d) data : %s\r\n", __FUNCTION__, __LINE__, paj7220_data);
    oled_show_data(paj7220_data, strlen(paj7220_data));
    if (strncmp(paj7220_data, STR_UP, STR_UP_LEN) == 0) {
        rgb_led_strip_add_brightness();
    } else if (strncmp(paj7220_data, STR_DOWN, STR_DOWN_LEN) == 0) {
        rgb_led_strip_min_brightness();
    } else if ((strncmp(paj7220_data, STR_COUNT_CLOCKWISE, STR_COUNT_CLOCKWISE_LEN) == 0) ||
               (strncmp(paj7220_data, CMD_PREV_MODE, CMD_PREV_MODE_LEN) == 0)) {
        rgb_led_strip_perv_mode();
    } else if ((strncmp(paj7220_data, STR_CLOCKWISE, STR_CLOCKWISE_LEN) == 0) ||
               (strncmp(paj7220_data, CMD_NEXT_MODE, CMD_NEXT_MODE_LEN) == 0)) {
        rgb_led_strip_next_mode();
    } else if (strncmp(paj7220_data, STR_FORWARD, STR_FORWARD_LEN) == 0) {
        rgb_led_strip_set_on();
    } else if ((strncmp(paj7220_data, STR_BACKWARD, STR_BACKWARD_LEN) == 0) ||
               (strncmp(paj7220_data, STR_WAVE, STR_WAVE_LEN) == 0)) {
        rgb_led_strip_set_off();
    } else if ((strncmp(paj7220_data, STR_LEFT, STR_LEFT_LEN) == 0) ||
               (strncmp(paj7220_data, CMD_PREV_SENCE, CMD_PREV_SENCE_LEN) == 0)) {
        rgb_led_strip_perv_sence();
    } else if ((strncmp(paj7220_data, STR_RIGHT, STR_RIGHT_LEN) == 0) ||
               (strncmp(paj7220_data, CMD_NEXT_SENCE, CMD_NEXT_SENCE_LEN) == 0)) {
        rgb_led_strip_next_sence();
    } else if (strncmp(paj7220_data, CMD_TOGGLE_LED, CMD_TOGGLE_LED_LEN) == 0) {
        rgb_led_strip_toggle();
    }
}

int parse_json_cammand(char *json_string)
{
    // 解析JSON字符串
    cJSON *root = cJSON_Parse(json_string);
    if (root == NULL) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL) {
            osal_printk("Error before: [%s]\n", error_ptr);
        }
        return 1;
    }
    // 提取数据
    cJSON *type = cJSON_GetObjectItem(root, CMD_TYPE);
    if (cJSON_IsString(type) && (type->valuestring != NULL)) {
        osal_printk("Type: %s\n", type->valuestring);
        if ((strcmp((const char *)type->valuestring, (const char *)CMD_TYPE_PAJ7620U2) == 0) ||
            (strcmp((const char *)type->valuestring, (const char *)CMD_TYPE_WIFI_CMD) == 0)) {
            cJSON *cmd = cJSON_GetObjectItem(root, CMD_NAME_CMD);
            if (cJSON_IsString(cmd) && (cmd->valuestring != NULL)) {
                osal_printk("cmd: %s\n", cmd->valuestring);
                handle_paj7620_cb_para(cmd->valuestring);
            }
        } else if (strcmp((const char *)type->valuestring, (const char *)CMD_TYPE_WIFI_INFO) == 0) {
            cJSON *j_ssid = cJSON_GetObjectItem(root, CMD_NAME_SSID);
            cJSON *j_password = cJSON_GetObjectItem(root, CMD_NAME_PASSWD);
            if (cJSON_IsString(j_ssid) && (j_ssid->valuestring != NULL)) {
                osal_printk("\r\n%s SSID: %s\n", __FUNCTION__, j_ssid->valuestring);
            }
            if (cJSON_IsString(j_password) && (j_password->valuestring != NULL)) {
                osal_printk("\r\n%s Password: %s\n", __FUNCTION__, j_password->valuestring);
            }
            rgb_master_wifi_info_t wifi_info;
            (void)memset_s(&wifi_info, sizeof(wifi_info), 0, sizeof(wifi_info));
            (void)memcpy_s(wifi_info.ssid, sizeof(wifi_info.ssid), j_ssid->valuestring, strlen(j_ssid->valuestring));
            (void)memcpy_s(wifi_info.password, sizeof(wifi_info.password), j_password->valuestring,
                           strlen(j_password->valuestring));
            int ret = key_value_rgb_master_wifi_info_write((uint8_t *)&wifi_info, sizeof(wifi_info));
            osal_printk("\r\n%s key_value_rgb_master_wifi_info_write ret: 0x%x\n", __FUNCTION__, ret);
            osal_mdelay(NV_WRITE_DELAY_TIME_MS);
            osal_printk("Setting Wifi Info reboot\n");
            hal_reboot_chip();
        } else if (strcmp((const char *)type->valuestring, (const char *)CMD_TYPE_LED_NUM) == 0) {
            cJSON *value = cJSON_GetObjectItem(root, CMD_NAME_VALUE);
            if (cJSON_IsString(value) && (value->valuestring != NULL)) {
                osal_printk("value: %s\n", value->valuestring);
                uint8_t g_ledNumValue = atoi(value->valuestring);
                uint16_t value_length = 1;
                int ret = key_value_rgb_master_led_number_write(&g_ledNumValue, value_length);
                osal_printk("\r\n%s key_value_rgb_master_led_number_write val_str:%s val_int:%d ret: 0x%x\n",
                            __FUNCTION__, value->valuestring, g_ledNumValue, ret);
                osal_mdelay(NV_WRITE_DELAY_TIME_MS);
                osal_printk("Setting led number reboot\n");
                hal_reboot_chip();
            }
        } else if (strcmp((const char *)type->valuestring, (const char *)CMD_TYPE_BRIGHTNESS) == 0) {
            cJSON *value = cJSON_GetObjectItem(root, CMD_NAME_VALUE);
            if (cJSON_IsString(value) && (value->valuestring != NULL)) {
                osal_printk("value: %s\n", value->valuestring);
                uint8_t g_brightness_value = atoi(value->valuestring);
                rgb_led_strip_set_brightness(g_brightness_value);
            }
        }
    }
    // 清理内存
    cJSON_Delete(root);
    return 0;
}
#endif

int parse_json_wifi_info(char *json_string)
{
    cJSON *whole = NULL;
    whole = cJSON_Parse(json_string);
    if (whole == NULL) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL) {
            osal_printk("Error before: %s\n", error_ptr);
        }
        free(json_string);
        return 1;
    }
    cJSON *j_ssid = cJSON_GetObjectItem(whole, "ssid");
    cJSON *j_password = cJSON_GetObjectItem(whole, "password");
    if (cJSON_IsString(j_ssid) && (j_ssid->valuestring != NULL)) {
        osal_printk("\r\n%s SSID: %s\n", __FUNCTION__, j_ssid->valuestring);
    }
    if (cJSON_IsString(j_password) && (j_password->valuestring != NULL)) {
        osal_printk("\r\n%s Password: %s\n", __FUNCTION__, j_password->valuestring);
    }
    rgb_master_wifi_info_t wifi_info;
    (void)memset_s(&wifi_info, sizeof(wifi_info), 0, sizeof(wifi_info));
    (void)memcpy_s(wifi_info.ssid, sizeof(wifi_info.ssid), j_ssid->valuestring, strlen(j_ssid->valuestring));
    (void)memcpy_s(wifi_info.password, sizeof(wifi_info.password), j_password->valuestring,
                   strlen(j_password->valuestring));
    int ret = key_value_rgb_master_wifi_info_write((uint8_t *)&wifi_info, sizeof(wifi_info));
    osal_printk("\r\n%s key_value_ssid_write ret: 0x%x\n", __FUNCTION__, ret);
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
    create_json_wifi_info(j_ssid->valuestring, j_password->valuestring);
#endif
    cJSON_Delete(whole);
    free(json_string);
    osal_mdelay(NV_WRITE_DELAY_TIME_MS);
    osal_printk("Setting Wifi Info reboot\n");
    hal_reboot_chip();
    return 0;
}

int parse_json_wifi_led_num(char *json_string)
{
    cJSON *root = cJSON_Parse(json_string);
    if (root == NULL) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL) {
            osal_printk("Error before: %s\n", error_ptr);
        }
        free(json_string);
        return;
    }
    cJSON *ledCount = cJSON_GetObjectItem(root, "ledCount");
    if (cJSON_IsString(ledCount)) {
        osal_printk("\r\n%s ledCount: %s\r\n", __FUNCTION__, ledCount->valuestring);
        uint16_t led_num_length = 1;
        uint8_t led_num_value = atoi(ledCount->valuestring);
        int ret = key_value_rgb_master_led_number_write(&led_num_value, led_num_length);
        osal_printk("\r\n%s key_value_rgb_master_led_number_write led_num_value: %d led_num_length:%d ret: 0x%x\n",
                    __FUNCTION__, led_num_value, led_num_length, ret);
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
        create_json_wifi_led_num(ledCount->valuestring);
#endif
    }
    cJSON_Delete(root);
    free(json_string);
    osal_mdelay(NV_WRITE_DELAY_TIME_MS);
    osal_printk("Set LED Number Info reboot\n");
    hal_reboot_chip();
}

int parse_json_wifi_brightness(char *json_string)
{
    cJSON *root = cJSON_Parse(json_string);
    osal_printk("\r\ncJSON_Parse: %s(%d)\r\n", __FUNCTION__, __LINE__);
    if (root == NULL) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL) {
            osal_printk("Error before: %s\n", error_ptr);
        }
        free(json_string);
        return;
    }
    osal_printk("\r\ncJSON_Parse: %s(%d)\r\n", __FUNCTION__, __LINE__);
    cJSON *brightness = cJSON_GetObjectItem(root, "brightness");
    osal_printk("\r\n cJSON_GetObjectItem: %s(%d)\r\n", __FUNCTION__, __LINE__);
    if (cJSON_IsString(brightness)) {
        osal_printk("\r\n%s brightness: %s\r\n", __FUNCTION__, brightness->valuestring);
        uint8_t g_brightness_value = atoi(brightness->valuestring);
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_SERVER)
        uint16_t brightness_value_length = 1;
        int ret = key_value_rgb_master_led_brightness_write(&g_brightness_value, brightness_value_length);
        osal_printk(
            "\r\n%s key_value_rgb_master_led_brightness_write brightness_value: %d "
            "brightness_value_length:%d ret: 0x%x\n",
            __FUNCTION__, g_brightness_value, brightness_value_length, ret);
        create_json_wifi_brightness(brightness->valuestring);
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_RGB_MASTER_CLIENT)
        rgb_led_strip_set_brightness(g_brightness_value);
#endif
    }
    cJSON_Delete(root);
    free(json_string);
}
